import {
  getViewer,
  isViewer,
  ViewerNameType,
  isNumber,
  isString,
} from "yt-cesium";
import { JulianDate } from "cesium";
import dayjs, { Dayjs, isDayjs } from "dayjs";

export * from "./synchronizeTime";

export const enum TimeType {
  currentTime = "currentTime",
  startTime = "startTime",
  stopTime = "stopTime",
}

/**
 * 获取 JulianDate的当前时间
 */
export const getCurrentTimeJulian = generateTimeJulian(TimeType.currentTime);

/**
 * 获取 DayJs 的当前时间
 */
export const getCurrentTimeDayJs = generateTimeDayJs(getCurrentTimeJulian);

/**
 * 使用 JulianDate 数据 设置 开始时间
 */
export const setCurrentTimeJulian = generateSetTimeJulian(TimeType.currentTime);

/**
 * 设置开始时间 兼容各种时间格式
 * @param time
 */
export function setCurrentTime(time: JulianDate | Dayjs | string | number) {
  try {
    if (isString(time) || isNumber(time) || isDayjs(time)) {
      return setCurrentTimeJulian(dayJsToJulianDate(time));
    }
    setCurrentTimeJulian(time);
  } catch (e) {
    console.error(e);
  }
}

export const getStartTimeJulian = generateTimeJulian(TimeType.startTime);

export const getStartTimeDayJs = generateTimeDayJs(getStartTimeJulian);

export const setStartTimeJulian = generateSetTimeJulian(TimeType.startTime);

export function setStartTime(time: JulianDate | Dayjs | string | number) {
  if (isString(time) || isNumber(time) || isDayjs(time)) {
    return setStartTimeJulian(dayJsToJulianDate(time));
  }
  setStartTimeJulian(time);
}

export const getStopTimeJulian = generateTimeJulian(TimeType.stopTime);

export const getStopTimeDayJs = generateTimeDayJs(getStopTimeJulian);

export const setStopTimeJulian = generateSetTimeJulian(TimeType.stopTime);

export function setStopTime(time: JulianDate | Dayjs | string | number) {
  if (isString(time) || isNumber(time) || isDayjs(time)) {
    return setStopTimeJulian(dayJsToJulianDate(time));
  }
  setStopTimeJulian(time);
}

/**
 * 生成 设置时间函数的高阶函数
 * @param timeType
 */
function generateSetTimeJulian(timeType: TimeType) {
  return function (time: JulianDate, viewerName?: ViewerNameType) {
    if (isViewer(viewerName)) {
      viewerName.clock[timeType] = time;
      return;
    }
    const viewer = getViewer(viewerName);
    viewer.clock[timeType] = time;
  };
}

/**
 * 生成获取 Julian时间实例的高阶函数
 * @param timeType
 */
function generateTimeJulian(timeType: TimeType) {
  return function (viewerName?: ViewerNameType) {
    if (isViewer(viewerName)) {
      return viewerName.clock[timeType];
    }
    const viewer = getViewer(viewerName);
    return viewer.clock[timeType];
  };
}

/**
 * 生成 获取dayjs实例的高阶函数
 * @param julianTimeFn
 */
function generateTimeDayJs(
  julianTimeFn: (viewerName: ViewerNameType) => JulianDate
) {
  return function (viewerName: ViewerNameType) {
    return JulianDateToDayJs(julianTimeFn(viewerName));
  };
}

/**
 * JulianDate 转 Dayjs
 * @param julianDate
 * @constructor
 */
export function JulianDateToDayJs(julianDate: JulianDate) {
  return dayjs(julianDate.toString());
}

/**
 * Dayjs 转 JulianDate
 * @param time
 * @constructor
 */
export function dayJsToJulianDate(time: dayjs.ConfigType) {
  return JulianDate.fromDate(dayjs(time).toDate());
}

/**
 * 设置无穷大结束时间
 */
export function setStopTimeInfinity() {
  setStopTime('9999/12/31 23:59:59')
}